package com.putable.nmc.dmv;

import com.putable.nmc.world.XRandom;
import com.putable.pqueue.PQueue;


public class BadTeller extends Teller {

	XRandom rand = new XRandom(Seed.seed);
	
	public BadTeller(PQueue pq){
		super(pq);
		setState(TellerState.WAITING.getInitialState());
		this.setTimeOfNextTask(rand.nextExponential(100));
		pq.insert(this);
	}
	/**
	 * @param m The number of managers
	 */
	private int m = 0;
	public void setNumManagers(int numM){
		m = numM;
	}


	@Override
	public void run(double time, CustomerLine cLine) {
		if(getState() == TellerState.BREAK || getState() == TellerState.LUNCH || getState() == TellerState.WAITING){
			if(rand.nextProbability(1/((5*m)+1))){
				setState(TellerState.BREAK);
				setTimeOfNextTask(time+rand.nextExponential(60*Math.max(1,15-m)));
				getPQueue().insert(this);
			}else{
				checkServe(time, cLine);
			}
		}else if(getState() == TellerState.SERVING){
			if(rand.nextProbability(1/(3*m+3))){
				setState(TellerState.LUNCH);
				setTimeOfNextTask(time + rand.nextExponential(60));
				this.getPQueue().insert(this);
			}else{
				checkServe(time, cLine);
			}
		}
	}
	@Override
	public CLineAble serve(CustomerLine cLine, PQueue pq, double time){
		CLineAble c = cLine.remove();
		pq.delete(c);
		c.setTimeOfNextTask(time+(2*c.getCit().getWillTakeTime()));
		c.setState(CustomerState.TRANSACTING);
		c.getPQueue().insert(c);
		return c;
	}
	/**
	 * Checks if the the line is empty and serves a customer if not
	 * @param time The current time
	 * @param cLine The Customer Line
	 */
	private void checkServe(double time, CustomerLine cLine){
		if(cLine.isEmpty()){
			setState(TellerState.BREAK);
			setTimeOfNextTask(time + rand.nextExponential(600));
			getPQueue().insert(this);
		}else{
			setState(TellerState.SERVING);
			CLineAble c = this.serve(cLine, this.getPQueue(), time);
			this.setTimeOfNextTask(time + 2 * c.getCit().getWillTakeTime());
			this.getPQueue().insert(this);
		}
	}


	@Override
	public String toString() {
		return "BadTeller [getState()=" + getState() + ", getTimeOfNextTask()="
				+ getTimeOfNextTask() + "]";
	}
	
}
